home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
graphic
/
jpegsrc4.zip
/
EXAMPLE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-14
|
28KB
|
632 lines
/*
* example.c
*
* This file is not actually part of the JPEG software. Rather, it provides
* a skeleton that may be useful for constructing applications that use the
* JPEG software as subroutines. This code will NOT do anything useful as is.
*
* This file illustrates how to use the JPEG code as a subroutine library
* to read or write JPEG image files. We assume here that you are not
* merely interested in converting the image to yet another image file format
* (if you are, you should be adding another I/O module to cjpeg/djpeg, not
* constructing a new application). Instead, we show how to pass the
* decompressed image data into or out of routines that you provide. For
* example, a viewer program might use the JPEG decompressor together with
* routines that write the decompressed image directly to a display.
*
* We present these routines in the same coding style used in the JPEG code
* (ANSI function definitions, etc); but you are of course free to code your
* routines in a different style if you prefer.
*/
/*
* Include file for declaring JPEG data structures.
* This file also includes some system headers like <stdio.h>;
* if you prefer, you can include "jconfig.h" and "jpegdata.h" instead.
*/
#include "jinclude.h"
/*
* <setjmp.h> is used for the optional error recovery mechanism shown in
* the second part of the example.
*/
#include <setjmp.h>
/******************** JPEG COMPRESSION SAMPLE INTERFACE *******************/
/* This half of the example shows how to feed data into the JPEG compressor.
* We present a minimal version that does not worry about refinements such
* as error recovery (the JPEG code will just exit() if it gets an error).
*/
/*
* To supply the image data for compression, you must define three routines
* input_init, get_input_row, and input_term. These routines will be called
* from the JPEG compressor via function pointer values that you store in the
* cinfo data structure; hence they need not be globally visible and the exact
* names don't matter. (In fact, the "METHODDEF" macro expands to "static" if
* you use the unmodified JPEG include files.)
*
* The input file reading modules (jrdppm.c, jrdgif.c, jrdtarga.c, etc) may be
* useful examples of what these routines should actually do, although each of
* them is encrusted with a lot of specialized code for its own file format.
*/
METHODDEF void
input_init (compress_info_ptr cinfo)
/* Initialize for input; return image size and component data. */
{
/* This routine must return five pieces of information about the incoming
* image, and must do any setup needed for the get_input_row routine.
* The image information is returned in fields of the cinfo struct.
* (If you don't care about modularity, you could initialize these fields
* in the main JPEG calling routine, and make this routine be a no-op.)
* We show some example values here.
*/
cinfo->image_width = 640; /* width in pixels */
cinfo->image_height = 480; /* height in pixels */
/* JPEG views an image as being a rectangular array of pixels, with each
* pixel having the same number of "component" values (color channels).
* You must specify how many components there are and the colorspace
* interpretation of the components. Most applications will use RGB data or
* grayscale data. If you want to use something else, you'll need to study
* and perhaps modify jcdeflts.c, jccolor.c, and jdcolor.c.
*/
cinfo->input_components = 3; /* or 1 for grayscale */
cinfo->in_color_space = CS_RGB; /* or CS_GRAYSCALE for grayscale */
cinfo->data_precision = 8; /* bits per pixel component value */
/* In the current JPEG software, data_precision must be set equal to
* BITS_IN_JSAMPLE, which is 8 unless you twiddle jconfig.h. Future
* versions might allow you to say either 8 or 12 if compiled with
* 12-bit JSAMPLEs, or up to 16 in lossless mode. In any case,
* it is up to you to scale incoming pixel values to the range
* 0 .. (1<<data_precision)-1.
* If your image data format is fixed at a byte per component,
* then saying "8" is probably the best long-term solution.
*/
}
/*
* This function is called repeatedly and must supply the next row of pixels
* on each call. The rows MUST be returned in top-to-bottom order if you want
* your JPEG files to be compatible with everyone else's. (If you cannot
* readily read your data in that order, you'll need an intermediate array to
* hold the image. See jrdtarga.c or jrdrle.c for examples of handling
* bottom-to-top source data using the JPEG code's portable mechanisms.)
* The data is to be returned into a 2-D array of JSAMPLEs, indexed as
* JSAMPLE pixel_row[component][column]
* where component runs from 0 to cinfo->input_components-1, and column runs
* from 0 to cinfo->image_width-1 (column 0 is left edge of image). Note that
* this is actually an array of pointers to arrays rather than a true 2D array,
* since C does not support variable-size multidimensional arrays.
* JSAMPLE is typically typedef'd as "unsigned char".
*/
METHODDEF void
get_input_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* Read next row of pixels into pixel_row[][] */
{
/* This example shows how you might read RGB data (3 components)
* from an input file in which the data is stored 3 bytes per pixel
* in left-to-right, top-to-bottom order.
*/
register FILE * infile = cinfo->input_file;
register JSAMPROW ptr0, ptr1, ptr2;
register long col;
ptr0 = pixel_row[0];
ptr1 = pixel_row[1];
ptr2 = pixel_row[2];
for (col = 0; col < cinfo->image_width; col++) {
*ptr0++ = (JSAMPLE) getc(infile); /* red */
*ptr1++ = (JSAMPLE) getc(infile); /* green */
*ptr2++ = (JSAMPLE) getc(infile); /* blue */
}
}
METHODDEF void
input_term (compress_info_ptr cinfo)
/* Finish up at the end of the input */
{
/* This termination routine will very often have no work to do, */
/* but you must provide it anyway. */
/* Note that the JPEG code will only call it during successful exit; */
/* if you want it called during error exit, you gotta do that yourself. */
}
/*
* That's it for the routines that deal with reading the input image data.
* Now we have overall control and parameter selection routines.
*/
/*
* This routine must determine what output JPEG file format is to be written,
* and make any other compression parameter changes that are desirable.
* This routine gets control after the input file header has been read
* (i.e., right after input_init has been called). You could combine its
* functions into input_init, or even into the main control routine, but
* if you have several different input_init routines, it's a definite win
* to keep this separate. You MUST supply this routine even if it's a no-op.
*/
METHODDEF void
c_ui_method_selection (compress_info_ptr cinfo)
{
/* If the input is gray scale, generate a monochrome JPEG file. */
if (cinfo->in_color_space == CS_GRAYSCALE)
j_monochrome_default(cinfo);
/* For now, always select JFIF output format. */
jselwjfif(cinfo);
}
/*
* OK, here is the main function that actually causes everything to happen.
* We assume here that the target filename is supplied by the caller of this
* routine, and that all JPEG compression parameters can be default values.
*/
GLOBAL void
write_JPEG_file (char * filename)
{
/* These three structs contain JPEG parameters and working data.
* They must survive for the duration of parameter setup and one
* call to jpeg_compress; typically, making them local data in the
* calling routine is the best strategy.
*/
struct Compress_info_struct cinfo;
struct Compress_methods_struct c_methods;
struct External_methods_struct e_methods;
/* Initialize the system-dependent method pointers. */
cinfo.methods = &c_methods; /* links to method structs */
cinfo.emethods = &e_methods;
/* Here we use the default JPEG error handl